<?php

namespace App\Manage;


use App\Models\AdminLog;
use App\Service\Option;


class Manage
{

    // 需要用的
    protected $error;
    protected $option;
    protected $view;
    protected $name;

    // 翻页等
    // $page $rows 查询的时候最好重新在获取一遍
    /*protected $rows;
    protected $page;
    protected $isPage;
    protected $id;*/

    // 控制器
    /*protected $module;
    protected $controller;
    protected $action;*/

    // 构造方法
    public function __construct()
    {
        $this->name = basename(str_replace('\\', '/', static::class));
        // 参数
        //$this->siteParam();
        // 初始化
        $this->initialize();
    }

    // 初始化
    protected function initialize() { }

    // 获取错误信息
    public function getError()
    {
        return $this->error;
    }

    #######################################################################################################
    ## 站点操作

    // 保存日志
    protected function addAdminLog($uid, $title, $en_title = '', $url = '', $remark = '')
    {
        //$ip = $this->option()->getIp();
        $ip = '';
        (new AdminLog())->saveLog($uid, $title, $en_title, $url, $ip, $remark);
    }

    #######################################################################################################
    ## 后台数据操作

    // 返回列表数据
    public function lists($myUser, $options = [])
    {
        $opt   = $this->option();
        $where = $this->listWhere();
        $page  = $opt->getData('page', 1, 'intval');
        $rows  = $opt->getData('rows', 15, 'intval');

        // 模型
        /** @var  $model \App\Models\Base */
        $model = $this->getModel();
        if($model === false){
            return $this->_returnFail('specify_the_operational_model');
            //return $this->_returnFail('请指定操作模型');
        }

        // 模型 和 查询
        if($where){
            $result = $model->listPageCache($where, $where, $page, $rows, "id DESC");
        } else{
            $result = $model->listPage($where, $page, $rows, "id DESC");
        }
        if($result === false){
            return $this->_returnFail($model->getError());
        }

        // 整理数据
        $result['list'] = $this->_afterList($result['list']);

        return $result;
    }

    // 返回列表数据
    public function all()
    {
        // 模型
        /** @var  $model \App\Models\Base */
        $model = $this->getModel();
        if($model === false){
            return $this->_returnFail('specify_the_operational_model');
            //return $this->_returnFail('请指定操作模型');
        }

        // 模型 和 查询
        $lists = $model->getList([], 0, "id DESC");
        if($lists === false){
            return $this->_returnFail($model->getError());
        }

        // 整理数据
        $lists = $this->_afterList($lists);

        return $lists;
    }

    // 删除
    public function del($myUser, $options = [])
    {
        $opt = $this->option();
        $id  = $opt->getData('id', 0, 'intval');
        $ids = $opt->getData('ids', [], 'is_array');
        // 修改记录
        if(empty($id) && empty($ids)){
            //return $this->_returnFail('请指定删除记录！');
            return $this->_returnFail('select_operation_id');
        }

        // 模型
        /** @var  $model \App\Models\Base */
        $model = $this->getModel();
        if($model === false){
            return $this->_returnFail('specify_the_operational_model');
            //return $this->_returnFail('请指定操作模型');
        }

        // 条件
        $where = [];
        if($id){
            $where[] = ['id', '=', $id];
        }
        if($ids){
            $where[] = [
                function($qq) use ($ids) {
                    $qq = $qq->whereIn('id', $ids);
                },
            ];
        }

        // 查询
        $lists = $model->where($where)->get()->toArray();;  //->recycle()
        if(empty($lists)){
            return $this->_returnFail('data_delete_has_not_exist');
            //return $this->_returnFail('你要删除的数据不存在！！');
        }

        // 缓存操作
        $model->deleteCacheList($lists);

        // 删除
        $res = $model->where($where)->delete();

        return true;
    }

    // 软删除
    public function softDel($field = 'status', $myUser = [], $options = [])
    {
        $opt = $this->option();
        $id  = $opt->getData('id', 0, 'intval');
        $ids = $opt->getData('ids', [], 'is_array');
        // 修改记录
        if(empty($id) && empty($ids)){
            //return $this->_returnFail('请指定删除记录！');
            return $this->_returnFail('select_operation_id');
        }

        // 模型
        /** @var  $model \App\Models\Base */
        $model = $this->getModel();
        if($model === false){
            return $this->_returnFail('specify_the_operational_model');
            //return $this->_returnFail('请指定操作模型');
        }

        // 条件
        $where = [];
        if($id){
            $where[] = ['id', '=', $id];
        }
        if($ids){
            $where[] = [
                function($qq) use ($ids) {
                    $qq = $qq->whereIn('id', $ids);
                },
            ];
        }

        // 查询
        $lists = $model->where($where)->get()->toArray();
        if(empty($lists)){
            //return $this->_returnFail('你要删除的数据不存在！！');
            return $this->_returnFail('data_delete_has_not_exist');
        }

        // 缓存操作
        $model->deleteCacheList($lists);

        // 删除
        $res = $model->where($where)->update([$field => -1]);

        return true;
    }

    // 查找
    public function show($myUser, $options = [])
    {
        $opt = $this->option();
        $id  = $opt->getData('id', 0, 'intval');
        if(empty($id)){
            //return $this->_returnFail('请指定查看记录！');
            return $this->_returnFail('select_operation_id');
        }

        // 模型
        /** @var  $model \App\Models\Base */
        $model   = $this->getModel();
        $isBuild = $opt->getHeader('Build-Admin', 0, 'intval');
        if($model === false){
            return $this->_returnFail('specify_the_operational_model');
            //return $this->_returnFail('请指定操作模型');
        }

        // 执行
        $where = $this->showWhere();
        $info  = $model->oneFindCache([], $where);
        if($info === false){
            return $this->_returnFail($model->getError());
        }

        // 权限处理
        if($info){
            $info['auths'] = is_array($info['auth']) ? $info['auth'] : json_decode($info['auth'], true);
        }

        // 如果是build-admin
        if($isBuild){
            return ['row' => $info];
        }

        return $info;
    }

    // 改变（直接修改，软删除，改变状态，排序）
    public function edit($myUser, $options = [])
    {
        $opt = $this->option();
        $id  = $opt->getData('id', 0, 'intval');
        if(empty($id)){
            //return $this->_returnFail('请指定查看记录！');
            return $this->_returnFail('select_operation_id');
        }

        // 数据
        $data = $this->_postData();
        if(empty($data)){
            $data = $this->_before_edit();
        }
        if($data === false){
            return false;
        }

        // 模型
        /** @var  $model \App\Models\Base */
        $model = $this->getModel();
        if($model === false){
            return $this->_returnFail('specify_the_operational_model');
            //return $this->_returnFail('请指定操作模型');
        }

        // 组合数据
        $data = $model->filterField($data, true);
        if($data === false){
            return $this->_returnFail($model->getError());
        }
        if(empty($data)){
            //return $this->_returnFail('不能修改为空！');
            return $this->_returnFail('send_data_to_be_modify');
        }

        // 验证
        if(in_array($model->getTable(), ['admin', 'user',])){
            $result = $model->checkData($data, __FUNCTION__);
            if($result === false){
                return false;
            }
        }


        // 执行
        $where  = $this->editWhere();
        $result = $model->oneEdit($where, $data);
        if($result === false){
            return $this->_returnFail($model->getError());
        }

        return true;
    }

    // 树状
    public function add($myUser, $options = [])
    {
        // 数据
        $data = $this->_postData();
        if(empty($data)){
            $data = $this->_before_add();
        }
        if($data === false){
            return false;
        }

        // 模型
        /** @var  $model \App\Models\Base */
        $model = $this->getModel();
        if($model === false){
            return $this->_returnFail('specify_the_operational_model');
            //return $this->_returnFail('请指定操作模型');
        }

        // 组合数据
        $data = $model->filterField($data, true);
        if($data === false){
            return $this->_returnFail($model->getError());
        }
        if(empty($data)){
            //return $this->_returnFail('请填写添加的数据！');
            return $this->_returnFail('add_the_saved_data');
        }

        // 验证
        if(in_array($model->getTable(), ['admin', 'user',])){
            $result = $model->checkData($data, __FUNCTION__);
            if($result === false){
                return false;
            }
        }

        // 保存
        $result = $model->oneAdd($data);
        if($result === false){
            return $this->_returnFail($model->getError());
        }

        return true;
    }

    // 列表条件
    protected function listWhere() { return []; }


    protected function editWhere() { return ['id' => $this->id()]; }

    protected function showWhere() { return ['id' => $this->id()]; }


    // 模型
    protected function getModel()
    {
        return false;
    }

    // 检查数据
    protected function checkData($data, $sceneName = 'add')
    {
        return $data;
    }

    // 添加、修改的数据
    protected function _postData()
    {
        return [];
    }

    // 添加的数据
    protected function _before_add()
    {
        return [];
    }

    // 修改的数据
    protected function _before_edit()
    {
        return [];
    }

    // 列表数据整理
    protected function _afterList($list) { return $list; }


    #######################################################################################################
    ## 其他操作

    // 站点常用参数
    protected function siteParam()
    {
        /**
         * 实体 => 符号
         * htmlspecialchars 中文不会乱码（获取的时候过滤，取出数据库的时候也要 htmlspecialchars_decode 过滤）
         * htmlentities  必须制定编码，不然中文乱码
         *
         * 反函数
         * html_entity_decode
         * htmlspecialchars_decode
         */

        // 当前文件名
        $option = $this->option();
        $data   = $option->getData();

        // 控制器
        $parameters       = $option->request()->route()->parameters;
        $this->controller = $data['controller'] ?? ($parameters['controller'] ?? '');
        $this->action     = $data['action'] ?? ($parameters['action'] ?? '');
        $this->module     = $data['module'] ?? ($parameters['module'] ?? 'frontend');

        // 控制器和方法可能是自定义的
        $option->request()->offsetUnset('controller');
        $option->request()->offsetUnset('action');

        //$this->is_debug = Env::get('app_debug');
        $this->isPage = empty($option->getData('page')) ? true : false;
        $this->page   = $option->getData('page', 1, 'intval');
        $this->rows   = $option->getData('rows', 10, 'intval');
        $this->id     = $option->getData('id', 0, 'intval');
        if($this->page < 1){
            $this->page = 1;
        }
        if($this->rows < 1 || $this->rows > 1000){
            $this->rows = 15;
        }

        // 如果重新搜索 变为第一页
        /*if($this->request->isPost()){
            $this->page = 1;
        }*/
    }

    // 日志记录
    protected function log($param, $msg)
    {
        $logger = new LogFile();
        $logger->write($param, $msg);
    }

    // 实例化逻辑参数
    protected function option()
    {
        if(empty($this->option)){
            $this->option = new Option();
        }

        return $this->option;
    }

    // 获取id
    protected function id()
    {
        return $this->option()->getData('id', 0, 'intval');
    }

    // 获取当前ip
    protected function ip()
    {
        return $this->option()->getIp();
    }

    // 返回错误
    protected function _returnFail($error)
    {
        $this->error = $error;

        return false;
    }

    #######################################################################################################
    // 于构建前置与后置操作方法
    public function __call($method, $parameters)
    {
        $before = '_before_'.$method;
        $after  = '_after_'.$method;

        // 前置操作
        if(method_exists($this, $before)){
            $this->{$before}(...array_values($parameters));
        }

        $result = $this->{$method}(...array_values($parameters));

        // 后置操作
        if(method_exists($this, $after)){
            $this->{$after}(...array_values($parameters));
        }

        return $result;
    }

}
